package com.myk.game.heroscuffle.game;

import androidx.annotation.IntRange;

import com.myk.game.heroscuffle.utils.SC;

import java.util.ArrayList;
import java.util.List;

/**
 * 游戏上场英雄池
 */
public class HeroPool {

    //当前游戏引用
    private final Game game;
    //上场的英雄集合
    private final List<Hero> heroList;

    /**
     * 当前正在行动中的英雄
     */
    public Hero curActionHero;

    public HeroPool(Game game) {
        this.game = game;
        this.heroList = new ArrayList<>();
    }

    /**
     * 打印所有英雄面板信息
     */
    public void printOriginHeroes() {
        for (Hero hero : heroList) {
            game.ui.printlnMsg(hero.getOriginInfo());
            game.ui.sleepShortly();
        }
    }

    /**
     * 打印所有存活的英雄信息，显示hp占比，不显示技能，玩家操作的英雄会有特殊标识。
     */
    public void printAliveHeroes() {
        for (Hero hero : heroList) {
            if (hero.state.isAlive) {
                game.ui.printlnMsg(hero.getStateInfo());
                game.ui.sleepShortly();
            }
        }
    }

    /**
     * 弹窗显示所有英雄当前详细信息
     */
    public void showHeroesCurrentInfoDialog() {
        StringBuilder sb = new StringBuilder();
        for (Hero hero : heroList) {
            String stateSymbol = hero.state.isPlayer ? "  o" : (hero.state.isActioned ? "  √" : "  x");
            StringBuilder info = new StringBuilder(hero.NAME + "(" + hero.ELE.text + ")  hp:" + hero.hp + "/" + hero.HP + "  atk:" + hero.atk + "  def:" + hero.def + stateSymbol);
            if (hero.SKILLS.size() > 0 || hero.SIGNS.size() > 0) {
                info.append(SC.TLI);
            }
            for (Skill skill : hero.SKILLS) {
                info.append(skill.SKILL_NAME).append(skill.isReady() ? "√" : "×").append("  ");
            }
            info.append("    ");
            for (Sign sign : hero.SIGNS) {
                info.append(sign.getObviousName());
                info.append("  ");
            }
            sb.append(info).append("\n");
        }
        game.ui.showLargeTextDialog("当前英雄状态详情", sb.toString());
    }

    /**
     * 从school中随机召唤指定数量的英雄上场
     */
    public void summonHeroes(int gameHeroCount) {
        //新建一组初始英雄集合来召唤
        HeroSchool school = new HeroSchool();
        for (int i = 0; i < gameHeroCount; i++) {
            Hero hero = school.randomTakeHero();
            heroList.add(hero);
        }
        //等所有英雄上场后主动通知上场英雄回调
        for (Hero hero : heroList) {
            hero.summon(game);
        }
    }

    /**
     * 根据顺序索引获取舞台上的英雄
     */
    public Hero getHeroFromList(int index) {
        return heroList.get(index);
    }

    /**
     * 随机选择一名当前存活且未行动过的英雄
     */
    public void chooseCurActionHero() {
        //获取或者且未行动过的英雄列表
        List<Hero> unHeroes = getAllAliveHeroesBy(item -> !item.state.isActioned);
        //随机选中一个作为当前行动的英雄
        curActionHero = unHeroes.get((int) (Math.random() * unHeroes.size()));
        curActionHero.setActioned();
        //移动选中英雄顺序到列表的末尾，这样回合结束时的打印，会和本回合行动顺序一致。
        heroList.remove(curActionHero);
        heroList.add(heroList.size(), curActionHero);
    }

    /**
     * 所有Hero的行动状态切换为false
     */
    public void clearAllActioned() {
        for (Hero hero : heroList) {
            hero.clearActioned();
        }
    }

    /**
     * 判断所有活着的Hero是否都行动了
     */
    public boolean isAllActioned() {
        for (Hero hero : heroList) {
            if (!hero.state.isActioned && hero.state.isAlive) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取存活的英雄的数量
     */
    public int getAliveCount() {
        int count = 0;
        for (Hero hero : heroList) {
            if (hero.state.isAlive) {
                count++;
            }
        }
        return count;
    }

    /**
     * 获取所有活着的英雄
     */
    public List<Hero> getAllAliveHeroes() {
        List<Hero> liveHeroes = new ArrayList<>();
        for (Hero hero : heroList) {
            if (hero.state.isAlive) {
                liveHeroes.add(hero);
            }
        }
        return liveHeroes;
    }

    /**
     * 随机获取一个英雄（存活的）
     */
    public Hero getAnyoneAliveHero(Hero... excepts) {
        List<Hero> aliveHeroes = getAllAliveHeroes(); //先获取所有存活的英雄
        for (Hero except : excepts) {
            aliveHeroes.remove(except);  //再把除外的英雄移除掉
        }
        if (aliveHeroes.size() == 0) {
            return null; //若没有剩下的了，直接返回null
        }
        else {
            return aliveHeroes.get((int) (Math.random() * aliveHeroes.size())); //从剩下的随机选一个
        }
    }

    /**
     * 获取最符合要求的一个英雄 (得是活的)
     */
    public Hero getBestAliveHeroBy(Compare compare, Hero... excepts) {
        List<Hero> liveHeroes = getAllAliveHeroes(); //获取所有存活的英雄
        for (Hero except : excepts) {
            liveHeroes.remove(except); //去掉需要排除的
        }
        if (liveHeroes.size() == 0) return null; //如果没有剩下的就直接返回null，之后的代码就不需要进行非空检查了
        if (liveHeroes.size() == 1) return liveHeroes.get(0); //如果就剩下1个，就直接返回它，没必要检查了
        List<Hero> meetHeroes = new ArrayList<>(); //这个容器用于存放所有满足要求的英雄
        Hero challenged = liveHeroes.get(0); //先拿第一个当作比较对象
        meetHeroes.add(challenged); //记得把比较对象放到容器里
        liveHeroes.remove(challenged); //已经比较过的就不需要再比了，否则会加到meetHeroes里，最后随机选择的时候不公平
        for (Hero challenger : liveHeroes) {
            int m = compare.compare(challenged, challenger);
            if (m > 0) {
                meetHeroes.clear(); //旧的都不满足要求了，全部清掉
                challenged = challenger; //更换新的比较对象
                meetHeroes.add(challenged); //记得新的比较对象也要放进来
            }
            else if (m == 0) {
                meetHeroes.add(challenger); //和比较对象一样那就放到meetHeroes里备选
            }
        }
        return meetHeroes.get((int) (Math.random() * meetHeroes.size())); //从剩下的随机选一个,不可能为null,所以不用非空检查
    }

    /**
     * 获取所有符合筛选条件的英雄（活着的）
     */
    public List<Hero> getAllAliveHeroesBy(Filter filter, Hero... excepts) {
        List<Hero> liveHeroes = getAllAliveHeroes(); //获取所有存活的英雄
        for (Hero except : excepts) {
            liveHeroes.remove(except);
        }
        List<Hero> meetHeroes = new ArrayList<>(); //符合要求的英雄
        for (Hero hero : liveHeroes) {
            if (filter == null || filter.filter(hero)) {
                meetHeroes.add(hero);
            }
        }
        return meetHeroes;
    }

    /**
     * 筛选条件
     */
    public interface Filter {
        boolean filter(Hero item);
    }

    /**
     * 比较条件
     */
    public interface Compare {

        /**
         * @param challenged 当前最符合条件的
         * @param challenger 当前的挑战者
         * @return 满足条件返回1，相等返回0，否则返回-1，最好三种情况都要考虑
         */
        @IntRange(from = -1, to = 1)
        int compare(Hero challenged, Hero challenger);
    }
}
